import { useCallback, useEffect, useRef } from 'react';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
import Map from 'ol/Map';
import { fromLonLat, toLonLat } from 'ol/proj';
import { Vector as VectorLayer } from 'ol/layer';
import Feature from 'ol/Feature';
import { Point } from 'ol/geom';
import VectorSource from 'ol/source/Vector';
import { Fill, Stroke, Style, Text } from 'ol/style';
import CircleStyle from 'ol/style/Circle';
import { Tag } from 'antd';
import PositionSearch from './PositionSearch';
import { convertLngLonToNumber } from '@/utils/coordTransform';
import { STATION_DATA, STATION_MAP } from '@/environment';

interface Props {
  cityCode: string;
  station?: [number, number];
  onSelectStation?: (station: [number, number], stationName?: string) => void;
}

const default_position: [number, number] = [120.34, 30.24508];
const img_url = STATION_MAP;
const data_url = STATION_DATA;

const PositionSelect = (props: Props) => {
  const { t } = useTranslation();

  const { cityCode, station, onSelectStation } = props;

  const [select, setSelect] = useState<[number, number]>(station ?? default_position);

  const view = useCallback(
    (position: [number, number]) =>
      new View({
        projection: 'EPSG:3857',
        center: fromLonLat(position),
        zoom: 16,
        maxZoom: 18,
        minZoom: 1,
      }),
    [],
  );

  const layers = useCallback(
    (urls: string[]) =>
      urls.map(
        (url) =>
          new TileLayer({
            source: new XYZ({ url }),
          }),
      ),
    [],
  );

  const pointLayer = useCallback(
    (position: [number, number]) =>
      new VectorLayer({
        source: new VectorSource({
          features: [new Feature({ geometry: new Point(fromLonLat(position)) })],
        }),
        style: new Style({
          image: new CircleStyle({
            radius: 15,
            fill: new Fill({ color: 'white' }),
            stroke: new Stroke({ color: '#419ac1', width: 5 }),
          }),
          text: new Text({
            text: `+`, //文本
            font: 'bold 20px Semi',
            offsetX: 0,
            offsetY: 0,
            stroke: new Stroke({ color: 'white', width: 1 }),
          }),
        }),
      }),
    [],
  );

  const mapElement = useRef<Map>(null);

  const renderMap = useCallback(() => {
    mapElement.current = new Map({
      target: 'map',
      view: view(select),
      layers: [...layers([img_url, data_url]), pointLayer(select)],
      controls: [],
    });
  }, [layers, pointLayer, select, view]);

  const singleClick = useCallback(() => {
    mapElement.current?.on('singleclick', (e) => {
      const lonLat = toLonLat(e.coordinate);
      const location: [number, number] = [lonLat[0], lonLat[1]];
      setSelect(location);
      onSelectStation?.(location);
    });
  }, [onSelectStation]);

  useEffect(() => {
    if (mapElement.current) {
      mapElement.current.dispose();
    }
    renderMap();

    singleClick();
  }, [renderMap, singleClick]);

  const handleSelectSearchPosition = (value: string, name: string) => {
    const location = convertLngLonToNumber(value);
    setSelect(location);
    onSelectStation?.(location, name);
  };

  return (
    <div>
      {
        // cityCode &&
        <PositionSearch cityCode={cityCode} onSelect={handleSelectSearchPosition} />
      }
      <div id={'map'} className={'h-80 py-2'} />
      <div>
        <Tag>
          {t('metro.stationLongitude')}: {select[0]}
        </Tag>
        <Tag>
          {t('metro.stationLatitude')}: {select[1]}
        </Tag>
      </div>
    </div>
  );
};

export default PositionSelect;
